home *** CD-ROM | disk | FTP | other *** search
/ CD Actual Thematic 7: Programming / CDAT7.iso / Share / Codigo / hh / rsource.exe / Hexen Source / I_CYBER.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-01-12  |  6.5 KB  |  278 lines

  1. // I_cyber.c
  2.  
  3. #include <dos.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include "st_start.h"    // For ST_Message()
  7.  
  8.  
  9. // Prototypes
  10. unsigned char *I_AllocLow (int length);
  11.  
  12.  
  13. /*
  14. ====================================================
  15.  
  16. Doom control structure
  17.  
  18. The keybaord and joystick will add to the values set by the cyberman,
  19. to a maximum of 0x19000 for forwardmove and sidemove.  Angleturn is
  20. not bounded at all.
  21.  
  22. parm                    normal          fast
  23. -----           ------          ----
  24. forwardmove             0xc800          0x19000
  25. sidemove                0xc000          0x14000
  26. angleturn               0x2800000       0x5000000
  27.  
  28. The keyboard and joystick have a 1/3 second slow turn of 0x1400000 under
  29. normal speed to help aiming.
  30.  
  31.  
  32.  
  33. ====================================================
  34. */
  35. /* old ticcmd_t
  36. typedef struct
  37. {
  38.     char            forwardmove;            // *2048 for move
  39.     char            sidemove;                       // *2048 for move
  40.     short           angleturn;                      // <<16 for angle delta
  41.     short           consistancy;            // checks for net game
  42.     unsigned char            chatchar;
  43.     unsigned char           buttons;
  44. } ticcmd_t;
  45. */
  46. // ticcmd_t as it appears in h2def.h
  47. typedef struct
  48. {
  49.     char forwardmove;
  50.     char sidemove;
  51.     short angleturn;
  52.     short consistancy;
  53.     unsigned char chatchar;
  54.     unsigned char buttons;
  55.     unsigned char lookfly;
  56.     unsigned char arti;
  57. }ticcmd_t;
  58.  
  59.  
  60. #define BT_ATTACK               1
  61. #define BT_USE                  2
  62. #define BT_CHANGE               4                       // if true, the next 3 bits hold weapon num
  63. #define BT_WEAPONMASK   (8+16+32)
  64. #define BT_WEAPONSHIFT  3
  65.  
  66. //==================================================
  67. //
  68. // CyberMan detection and usage info
  69. //
  70. //==================================================
  71. #define DPMI_INT        0x31
  72. #define MOUSE_INT       0x33
  73.  
  74. #define DOSMEMSIZE      64      // enough for any SWIFT structure
  75.  
  76. typedef struct {
  77.    short        x;
  78.    short        y;
  79.    short        z;
  80.    short        pitch;
  81.    short        roll;
  82.    short        yaw;
  83.    short        buttons;
  84. } SWIFT_3DStatus;
  85.  
  86. // DPMI real mode interrupt structure
  87. static struct rminfo {
  88.     long EDI;
  89.     long ESI;
  90.     long EBP;
  91.     long reserved_by_system;
  92.     long EBX;
  93.     long EDX;
  94.     long ECX;
  95.     long EAX;
  96.     short flags;
  97.     short ES,DS,FS,GS,IP,CS,SP,SS;
  98. } RMI;
  99.  
  100. typedef struct {
  101.    unsigned char        deviceType;
  102.    unsigned char        majorVersion;
  103.    unsigned char        minorVersion;
  104.    unsigned char        absRelFlags;
  105.    unsigned char        centeringFlags;
  106.    unsigned char        reserved[5];
  107. } StaticDeviceData;
  108.  
  109. // values for deviceType:
  110. #define DEVTYPE_CYBERMAN        1
  111.  
  112. short                   selector;
  113. unsigned short  segment;                // segment of DOS memory block
  114. SWIFT_3DStatus  *cyberstat;
  115. int                             isCyberPresent;         // is CyberMan present?
  116.  
  117.  
  118. static  union REGS regs;
  119. static  struct SREGS sregs;
  120.  
  121.  
  122. extern  int mousepresent;
  123.  
  124. //===========================================================
  125. //
  126. // I_StartupCyberMan
  127. //
  128. // If a cyberman is present, init it and set isCyberPresent to 1
  129. //===========================================================
  130. void I_StartupCyberMan(void)
  131. {
  132.    StaticDeviceData *pbuf;
  133.  
  134.    ST_Message("  CyberMan: ");
  135.    isCyberPresent = 0;
  136.  
  137.    cyberstat = (SWIFT_3DStatus *)I_AllocLow (DOSMEMSIZE);
  138.    segment = (int)cyberstat>>4;
  139.  
  140.    pbuf = (StaticDeviceData *)cyberstat;
  141.    memset(pbuf, 0, sizeof (StaticDeviceData));
  142.  
  143.  
  144.    // Use DPMI call 300h to issue mouse interrupt
  145.    memset(&RMI, 0, sizeof(RMI));
  146.    RMI.EAX = 0x53C1;            // SWIFT: Get Static Device Data
  147.    RMI.ES = segment;
  148.    RMI.EDX = 0;
  149.    memset(&sregs, 0, sizeof (sregs));
  150.    regs.w.ax = 0x0300;          // DPMI: simulate interrupt
  151.    regs.w.bx = MOUSE_INT;
  152.    regs.w.cx = 0;
  153.    regs.x.edi = FP_OFF(&RMI);
  154.    sregs.es = FP_SEG(&RMI);
  155.    int386x( DPMI_INT, ®s, ®s, &sregs );
  156.  
  157.    if ((short)RMI.EAX != 1)
  158.    {
  159.       // SWIFT functions not present
  160.       ST_Message("Wrong mouse driver - no SWIFT support (AX=%04x).\n",
  161.              (unsigned)(short)RMI.EAX);
  162.    }
  163.    else if (pbuf->deviceType != DEVTYPE_CYBERMAN)
  164.    {
  165.       // no SWIFT device, or not CyberMan
  166.       if (pbuf->deviceType == 0)
  167.       {
  168.          ST_Message("no SWIFT device connected.\n");
  169.       }
  170.       else
  171.       {
  172.          ST_Message("SWIFT device is not a CyberMan! (type=%d)\n",
  173.                 pbuf->deviceType);
  174.       }
  175.    }
  176.    else
  177.    {
  178.       ST_Message("CyberMan %d.%02d connected.\n",
  179.              pbuf->majorVersion, pbuf->minorVersion);
  180.       isCyberPresent = 1;
  181.       mousepresent = 0;
  182.    }
  183. }
  184.  
  185.  
  186.  
  187. /*
  188. ===============
  189. =
  190. = I_ReadCyberCmds
  191. =
  192. ===============
  193. */
  194.  
  195.  
  196. int             oldpos;
  197.  
  198. void I_ReadCyberCmd (ticcmd_t *cmd)
  199. {
  200.     int             delta;
  201.  
  202.     // Use DPMI call 300h to issue mouse interrupt
  203.     memset(&RMI, 0, sizeof(RMI));
  204.     RMI.EAX = 0x5301;            // SWIFT: Get Position and Buttons
  205.     RMI.ES = segment;
  206.     RMI.EDX = 0;
  207.     memset(&sregs, 0, sizeof (sregs));
  208.     regs.w.ax = 0x0300;          // DPMI: simulate interrupt
  209.     regs.w.bx = MOUSE_INT;
  210.     regs.w.cx = 0;
  211.     regs.x.edi = FP_OFF(&RMI);
  212.     sregs.es = FP_SEG(&RMI);
  213.     int386x( DPMI_INT, ®s, ®s, &sregs );
  214.  
  215.     if (cyberstat->y < -7900)
  216.         cmd->forwardmove = 0xc800/2048;
  217.     else if (cyberstat->y > 7900)
  218.         cmd->forwardmove = -0xc800/2048;
  219.  
  220.     if (cyberstat->buttons & 4)
  221.         cmd->buttons |= BT_ATTACK;
  222.     if (cyberstat->buttons & 2)
  223.         cmd->buttons |= BT_USE;
  224.  
  225.     delta = cyberstat->x - oldpos;
  226.     oldpos = cyberstat->x;
  227.  
  228.     if (cyberstat->buttons & 1)
  229.     {       // strafe
  230.         if (cyberstat->x < -7900)
  231.             cmd->sidemove = -0xc800/2048;
  232.         else if (cyberstat->x > 7900)
  233.             cmd->sidemove = 0xc800/2048;
  234.         else
  235.             cmd->sidemove = delta*40/2048;
  236.     }
  237.     else
  238.     {
  239.         if (cyberstat->x < -7900)
  240.             cmd->angleturn = 0x280;
  241.         else if (cyberstat->x > 7900)
  242.             cmd->angleturn = -0x280;
  243.         else
  244.             cmd->angleturn = -delta*0xa/16;
  245.  
  246.     }
  247.  
  248. }
  249.  
  250.  
  251. void I_Tactile (int on, int off, int total)
  252. {
  253.     if (!isCyberPresent)
  254.         return;
  255.  
  256.     on /= 5;
  257.     off /= 5;
  258.     total /= 40;
  259.     if (on > 255)
  260.         on = 255;
  261.     if (off > 255)
  262.         off = 255;
  263.     if (total > 255)
  264.         total = 255;
  265.  
  266.     memset(&RMI, 0, sizeof(RMI));
  267.     RMI.EAX = 0x5330;            // SWIFT: Get Position and Buttons
  268.     RMI.EBX = on*256+off;
  269.     RMI.ECX = total;
  270.     memset(&sregs, 0, sizeof (sregs));
  271.     regs.w.ax = 0x0300;          // DPMI: simulate interrupt
  272.     regs.w.bx = MOUSE_INT;
  273.     regs.w.cx = 0;
  274.     regs.x.edi = FP_OFF(&RMI);
  275.     sregs.es = FP_SEG(&RMI);
  276.     int386x( DPMI_INT, ®s, ®s, &sregs );
  277. }
  278.